package com.kalaqia.picker.time;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.AppCompatTextView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.NumberPicker;

import java.lang.reflect.Field;
import java.util.Calendar;

/**
 * function:
 * project:TimeRangePickerLibrary
 * describe:
 * created owner:kalaqia 421407393@qq.com
 * created date:2017/11/27 0027 9:50
 */
//<editor-fold desc="version update log">
// updare owner:kalaqia  421407393@qq.com
// update datetime:2017/11/27 0027 9:50  
// update remark:
//</editor-fold>
public class TimeRangePickerDialog extends DialogFragment {

    String[] hour = new String[24];
    String[] minute = new String[60];

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        int i;
        for (i = 0; i < 24; i++) {
            hour[i] = String.valueOf(i);
        }
        for (i = 0; i < 60; i++) {
            if (i < 10) {
                minute[i] = "0" + i;
                continue;
            }
            minute[i] = String.valueOf(i);
        }
        return inflater.inflate(R.layout.dialog_time_picker, container, false);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.TimeRangePickerDialogTheme);
    }

    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            DisplayMetrics dm = new DisplayMetrics();
            if (getActivity() != null) {
                getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            }
            if (dialog.getWindow() != null) {
                dialog.getWindow().setLayout((int) (dm.widthPixels * 0.8), ViewGroup.LayoutParams.WRAP_CONTENT);
            }
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
        initData(view);
        initListener(view);
    }

    private final String timeFormat = "%s:%s";

    private void initData(View view) {
        //set p1 values for "from" hour
        p1.setMaxValue(hour.length - 1);
        p1.setDisplayedValues(hour);
        p1.setValue(fromCal.get(Calendar.HOUR_OF_DAY));
        p1.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

        //detects the change for p1 values
        p1.setOnValueChangedListener((numberPicker, i, i1) -> {

            p1.setValue(i1);
            setCalendar(fromCal, fromCal, p1, p2);
            setCalendar(toCal, fromCal, p1, p2);

            Log.e("toCal.set", "" + toCal.getTimeInMillis());
            p4.setValue(toCal.get(Calendar.HOUR_OF_DAY));
            setText();
        });

        p2.setMaxValue(minute.length - 1);
        p2.setDisplayedValues(minute);
        p2.setValue(fromCal.get(Calendar.MINUTE));
        p2.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

        //detects the change for p2 values
        p2.setOnValueChangedListener((numberPicker, i, i1) -> {
            p2.setValue(i1);
            setCalendar(fromCal, fromCal, p1, p2);

            p5.setValue(p2.getValue());
            setText();
        });


        p4.setMinValue(0);
        p4.setMaxValue(hour.length - 1);
        p4.setDisplayedValues(hour);
        p4.setValue(toCal.get(Calendar.HOUR_OF_DAY));
        p4.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

        p4.setOnValueChangedListener((numberPicker, i, i1) -> {
            p4.setValue(i1);

            setCalendar(toCal, toCal, p4, p5);

            if (toCal.getTimeInMillis() < fromCal.getTimeInMillis()) {
                p4.setValue(i);
                setCalendar(toCal, toCal, p4, p5);
            }

            //checking if time selected is more than 8 hours
//            if (fromCal.getTimeInMillis() + 28800000 < toCal.getTimeInMillis()) {
//                p4.setValue(i);
//                toCal.set(toCal.get(Calendar.YEAR), toCal.get(Calendar.MONTH), toCal.get(Calendar.DAY_OF_MONTH), oneToTwentyFour(hour[p4.getValue()], p6.getValue()), Integer.parseInt(minute[p5.getValue()]));
//            }

            //Set p6 value to AM or PM depending on Calender "toCal" time
//            if (AMorPM(toCal.get(Calendar.HOUR_OF_DAY)) == 1) {
//                p6.setValue(1);
//            } else {
//                p6.setValue(0);
//            }

            mToTime.setText(String.format(timeFormat, hour[p4.getValue()], minute[p5.getValue()]));
        });

        p5.setMinValue(0);
        p5.setMaxValue(minute.length - 1);
        p5.setDisplayedValues(minute);
        p5.setValue(p2.getValue());
        p5.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

        p5.setOnValueChangedListener((numberPicker, i, i1) -> {
            p5.setValue(i1);

            setCalendar(toCal, toCal, p4, p5);

            if (toCal.getTimeInMillis() < fromCal.getTimeInMillis()) {
                p5.setValue(i);
                setCalendar(toCal, toCal, p1, p2);
            }

            mToTime.setText(String.format(timeFormat, hour[p4.getValue()], minute[p5.getValue()]));
        });

        setText();

    }

    private void setCalendar(Calendar calendar1, Calendar calendar2, TimeNumberPicker hourPicker, TimeNumberPicker minutePicker) {
        calendar1.set(
                calendar2.get(Calendar.YEAR),
                calendar2.get(Calendar.MONTH),
                calendar2.get(Calendar.DAY_OF_MONTH),
                Integer.parseInt(hour[hourPicker.getValue()]),
                Integer.parseInt(minute[minutePicker.getValue()])
        );
    }

    //set the text according to the values in the number pickers
    private void setText() {
        mFromTime.setText(String.format(timeFormat, hour[p1.getValue()], minute[p2.getValue()]));
        mToTime.setText(String.format(timeFormat, hour[p4.getValue()], minute[p5.getValue()]));
//                setNumberPickerTextColor(p1,Color.BLACK);
    }

    public void show(FragmentManager manager) {
        try {
            if (isAdded()) {
                getDialog().show();
                return;
            }
            super.show(manager, getLocalTag());
        } catch (Exception e) {
            e.printStackTrace();
            try {
                manager.beginTransaction().add(this, getLocalTag())
                        .commitAllowingStateLoss();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mOnDismissListener != null) {
            mOnDismissListener.onDismiss(getDialog());
        }
    }

    protected DialogInterface.OnDismissListener mOnDismissListener;

    @SuppressWarnings("unused")
    public void setOnDismissListener(DialogInterface.OnDismissListener mOnDismissListener) {
        this.mOnDismissListener = mOnDismissListener;
    }

    protected String getLocalTag() {
        return "TimeRangePickerDialog";
    }

    private void initListener(View view) {
        mConfirm.setOnClickListener(v -> {
//            SimpleDateFormat format = new SimpleDateFormat("HH:mm");
//            String fTime = format.format(fromCal.getTime());
//            String tTime = format.format(toCal.getTime());

            String fTime = mFromTime.getText().toString().trim();
            String tTime = mToTime.getText().toString().trim();

            if (mOnConfirmListener != null) {
                mOnConfirmListener.onConfirm(fTime, tTime);
            }

            dismissAllowingStateLoss();
        });

        mCancel.setOnClickListener(v -> dismissAllowingStateLoss());
    }

    // Calender fromCal is for managing "from" time
    Calendar fromCal = Calendar.getInstance();

    final Calendar genCal = Calendar.getInstance();

    // Calender toCal is for managing "To" time
    final Calendar toCal = Calendar.getInstance();


    private TimeNumberPicker p1;
    private TimeNumberPicker p2;
    //    private TimeNumberPicker p3;
    private TimeNumberPicker p4;
    private TimeNumberPicker p5;
    //    private TimeNumberPicker p6;
    private AppCompatButton mCancel;
    private AppCompatButton mConfirm;
    private AppCompatTextView mFromTime;
    private AppCompatTextView mToTime;

    private void initView(View view) {
        p1 = view.findViewById(R.id.p1);
        p2 = view.findViewById(R.id.p2);
//        p3 = view.findViewById(R.id.p3);
        p4 = view.findViewById(R.id.p4);
        p5 = view.findViewById(R.id.p5);
//        p6 = view.findViewById(R.id.p6);
        setNumberPickerTextColor(p1);
        setNumberPickerTextColor(p2);
//        setNumberPickerTextColor(p3);
        setNumberPickerTextColor(p4);
        setNumberPickerTextColor(p5);
//        setNumberPickerTextColor(p6);


        mFromTime = view.findViewById(R.id.fromTime);
        mToTime = view.findViewById(R.id.toTime);
        mConfirm = view.findViewById(R.id.confirmOk);
        mCancel = view.findViewById(R.id.confirmNotOk);
    }

    public static boolean setNumberPickerTextColor(TimeNumberPicker numberPicker) {
        final int count = numberPicker.getChildCount();
        for (int i = 0; i < count; i++) {
            View child = numberPicker.getChildAt(i);
            if (child instanceof EditText) {
                try {
                    Field selectorWheelPaintField = numberPicker.getClass()
                            .getDeclaredField("mSelectorWheelPaint");
                    selectorWheelPaintField.setAccessible(true);
                    ((EditText) child).setTextSize(30);
                    numberPicker.invalidate();
                    return true;
                } catch (NoSuchFieldException e) {
                    Log.w("setNumberPicker", e);
                } catch (IllegalArgumentException e) {
                    Log.w("setNumberPicker", e);
                }
            }
        }
        return false;
    }

    private OnConfirmListener mOnConfirmListener;

    public void setOnConfirmListener(OnConfirmListener mOnConfirmListener) {
        this.mOnConfirmListener = mOnConfirmListener;
    }

    public interface OnConfirmListener {
        void onConfirm(String startTime, String endTime);
    }


}
